package org.sjs.dreamfly.browser.jsbridge

import android.content.Context
import android.webkit.WebView
import org.sjs.dreamfly.browser.BrowserConst
import org.sjs.dreamfly.common.base.Listener
import org.sjs.dreamfly.data.Config
import org.sjs.dreamfly.common.util.LogUtil
import java.io.InputStreamReader

object JsInjector {
    interface InjectStrategy {
        fun getMethods(): Int
        fun getPoints(): Int
    }

    interface InjectEventListener: Listener {
        override fun notify(vararg params: Any?) {
            onInjectEvent((params[0] as Array<*>)[0] as String, (params[0] as Array<*>)[1] as Int, (params[0] as Array<*>)[2] as Int)
        }
        fun onInjectEvent(url: String, point: Int, method: Int)
    }

    private fun inject(context: Context, url: String, webView: WebView) {
        LogUtil.d("url:$url")
        val stringBuilder = StringBuilder()
        val jsFileWebSitePath = Config.webSiteLists.find {
            url.startsWith(it.url)
        }?.jsFilePath
        if (jsFileWebSitePath.isNullOrEmpty()) return
        loadFile(context, "common.js", stringBuilder)
        loadFile(context, jsFileWebSitePath, stringBuilder)
        val result = buildScriptNode(stringBuilder.toString())
        LogUtil.d(result)
        webView.loadUrl("javascript:${result}")
    }
    fun executeJsMethod(context: Context, url: String, webView: WebView, method: Int) {
        LogUtil.d("url:$url, method:$method")
        inject(context, url, webView)
        val stringBuilder = StringBuilder()
        if (hasMethod(method, BrowserConst.InjectMethod.METHOD_MOVIE_LIST)) stringBuilder.append("snifferMovieList();")
        if (hasMethod(method, BrowserConst.InjectMethod.METHOD_PLAY_LIST)) stringBuilder.append("snifferPlayList();")
        if (hasMethod(method, BrowserConst.InjectMethod.METHOD_PLAY_INFO)) stringBuilder.append("snifferPlayInfo();")
        if (hasMethod(method, BrowserConst.InjectMethod.METHOD_REMOVE_ADS)) stringBuilder.append("removeAds();")
        if (hasMethod(method, BrowserConst.InjectMethod.METHOD_SEARCH_LIST)) stringBuilder.append("snifferSearchList();")
        val result = buildScriptNode(stringBuilder.toString())
        LogUtil.d(result)
        webView.loadUrl("javascript:${result}")
    }
    private fun buildScriptNode(content: String): String {
        val stringBuilder = StringBuilder()
        stringBuilder.append("var injectScript = document.createElement('script');")
        stringBuilder.append("injectScript.innerHTML = '")
        stringBuilder.append(content)
        stringBuilder.append("';")
        stringBuilder.append("document.body.appendChild(injectScript);")
        return stringBuilder.toString()
    }
    private fun loadFile(
        context: Context,
        jsFilePath: String,
        stringBuilder: StringBuilder
    ) {
        val inputStream = context.resources.assets.open(jsFilePath)
        InputStreamReader(inputStream).readLines().forEach {
            it.trim().let { line ->
                if (line.isNotEmpty() && !line.startsWith("//")) {
                    stringBuilder.append(it)
                }
            }
        }
        inputStream.close()
    }

    private fun hasMethod(flag: Int, mask: Int): Boolean {
        return flag and mask != 0
    }

    fun JsInjector.hasPoint(point: Int, mask: Int): Boolean {
        return point and mask != 0
    }
}